#include "peer_cluster.h"

NodePeerCluster::NodePeerCluster(Node *parent, NodePeerClusterParam params) :
    Node(parent)
{
    List<List<int>> tmp_895265592;
    for(int ii=0; ii<params.num_of_peer_group; ii+=1)
    {
        List<int> tmp_895265704;
        for(int jj=(params.peer_id_base)+((ii)*(params.num_of_peer)); jj<(params.peer_id_base)+(((ii)+(1))*(params.num_of_peer)); jj+=1)
        {
            tmp_895265704.append(jj);
        }
        tmp_895265592.append(tmp_895265704);
    }
    const_peer_ids = tmp_895265592;
    List<NodePeerGroup *> tmp_895264640;
    for(int temp_885079456=0; temp_885079456<const_peer_ids.size(); temp_885079456+=1)
    {
        List<int> peer_ids = const_peer_ids[temp_885079456];
        NodePeerGroupParam node_param_895264696;
        node_param_895264696.peer_id_base = peer_ids[0];
        node_param_895264696.num_of_peer = params.num_of_peer;
        node_param_895264696.softmem_size = params.softmem_size;
        node_param_895264696.num_of_main_memory = params.num_of_main_memory;
        node_param_895264696.num_of_alu = params.num_of_alu;
        node_param_895264696.multiplexer = params.multiplexer;
        node_param_895264696.total_peers = params.total_peers;
        node_param_895264696.base_ptrs = params.base_ptrs;
        tmp_895264640.append(new NodePeerGroup(this, node_param_895264696));
    }
    node_peer_groups = tmp_895264640;
    NodeMRunnerParam node_param_895263520;
    List<int> tmp_895326976;
    for(int ii=0; ii<(params.num_of_peer_group)*(params.num_of_peer); ii+=1)
    {
        tmp_895326976.append((params.peer_id_base)+(ii));
    }
    node_param_895263520.peer_ids = tmp_895326976;
    node_mrunner = new NodeMRunner(this, node_param_895263520);
    for(int ii=0; ii<(params.num_of_peer_group)-(1); ii+=1)
    {
        ChannelLoadFabric::connect(node_peer_groups[ii]->port_chain_out, node_peer_groups[(ii)+(1)]->port_chain_in);
    }
    ChannelLoadFabric::connect(node_peer_groups[-1]->port_chain_out, node_mrunner->port_message_in);
    ChannelLoadFabric::connect(node_mrunner->port_message_out, node_peer_groups[0]->port_chain_in);
    port_chain_out = node_mrunner->port_chain_out;
    port_chain_in = node_mrunner->port_chain_in;
    NodeRouterNanoOpParam node_param_895437008;
    node_param_895437008.routing_map = const_peer_ids;
    node_router_eop = new NodeRouterNanoOp(this, node_param_895437008);
    for(int ii=0; ii<params.num_of_peer_group; ii+=1)
    {
        ChannelExecOpFabric::connect(node_router_eop->port_senders[ii], node_peer_groups[ii]->port_nano_op_receiver);
    }
    port_nano_op_receiver = node_router_eop->port_receiver;
    List<NodeRouterLoad *> tmp_895438800;
    for(int temp_884954168=0; temp_884954168<params.num_of_main_memory; temp_884954168+=1)
    {
        NodeRouterLoadParam node_param_895438744;
        node_param_895438744.multiplexer = params.multiplexer;
        node_param_895438744.routing_map = const_peer_ids;
        tmp_895438800.append(new NodeRouterLoad(this, node_param_895438744));
    }
    node_router_load = tmp_895438800;
    for(int ii=0; ii<params.num_of_main_memory; ii+=1)
    {
        for(int jj=0; jj<params.num_of_peer_group; jj+=1)
        {
            ChannelLoadFabric::connect(node_router_load[ii]->port_senders[jj], node_peer_groups[jj]->port_memory_receivers[ii]);
        }
    }
    List<ChannelLoadFabricReceiver *> tmp_894260952;
    for(int ii=0; ii<params.num_of_main_memory; ii+=1)
    {
        tmp_894260952.append(node_router_load[ii]->port_receiver);
    }
    port_memory_receivers = tmp_894260952;
    List<NodeArbiterStore *> tmp_894261736;
    for(int temp_885114304=0; temp_885114304<params.num_of_peer_group; temp_885114304+=1)
    {
        NodeArbiterStoreParam node_param_894261680;
        node_param_894261680.num_of_receivers = params.num_of_peer_group;
        tmp_894261736.append(new NodeArbiterStore(this, node_param_894261680));
    }
    node_arbiter_store = tmp_894261736;
    for(int ii=0; ii<params.num_of_main_memory; ii+=1)
    {
        for(int jj=0; jj<params.num_of_peer_group; jj+=1)
        {
            ChannelStoreFabric::connect(node_peer_groups[jj]->port_memory_senders[ii], node_arbiter_store[ii]->port_receivers[jj]);
        }
    }
    List<ChannelStoreFabricSender *> tmp_895381688;
    for(int ii=0; ii<params.num_of_main_memory; ii+=1)
    {
        tmp_895381688.append(node_arbiter_store[ii]->port_sender);
    }
    port_memory_senders = tmp_895381688;
    NodeAndGateParam node_param_895382360;
    node_param_895382360.num_of_ports = ((params.num_of_peer_group)+(params.num_of_main_memory))+(1);
    node_halt_detect = new NodeAndGate(this, node_param_895382360);
    for(int ii=0; ii<params.num_of_peer_group; ii+=1)
    {
        node_peer_groups[ii]->port_halt->connect(node_halt_detect->port_and_ins[ii]);
    }
    for(int ii=0; ii<params.num_of_main_memory; ii+=1)
    {
        node_arbiter_store[ii]->port_halt->connect(node_halt_detect->port_and_ins[(params.num_of_peer_group)+(ii)]);
    }
    node_mrunner->port_halt->connect(node_halt_detect->port_and_ins[-1]);
    port_halt = node_halt_detect->port_and_out;
}

NodeTaskList NodePeerCluster::tasks() const
{
    NodeTaskList list;
    return list;
}